<?php

/** 
 * 控制器_买水
 * @property User_dev_mdl $userDev
 * @property Order_mdl $order
 * @property Water_price_mdl $price
 * @property Order_queue_mdl $orderQueue
 */
class Buy extends MY_Controller {
	/**
	 * 按次消费的一次取水秒数
	 */
	const ONCE_TAKE_SECS = 5;
	
	public function __construct() {
		parent::__construct ();
		$this->user = parent::getLoginUser();
		$this->load->model('Order_mdl','order');
		$this->load->model('User_dev_mdl','userDev');
		$this->load->model('Water_price_mdl','price');
		$this->load->model('Order_queue_mdl','orderQueue');
	}
	/**
	 * API:买水页数据
	 * 	余额及水价
	 */
	public function index(){
		$this->apiOutput->put('balance',(int) $this->user->balance)
						->put('price', $this->price->getPrice(BUY_MODE_NORMAL))
						->out();
	}
	/**
	 * 授权
	 *  传入参数:
	 *  	devID:设备ID
	 */
	public function acess(){
		$mode = $this->getMode ();
		$balance = ( int ) $this->user->balance;
		$price = $this->price->getPrice ( $mode );
		// 检查余额是否充足
		if ($balance < $price ['cold']) {
			$this->apiOutput->error ( '余额不足,请充值后再取水', - 99 );
		}
		// 检查该用户是否有未完成订单
		if ($this->order->checkUserHasUnfinishOrder ( $this->user->id )) {
			$this->apiOutput->error ( '您的账号有未完成的订单,请稍后再试!', - 3 );
		}
		// 输出
		$this->apiOutput->put ( 'balance', $balance )
						->put ( 'price', $price )
						->out ();
	}
	/**
	 * API:开始买水
	 * 传入参数:
	 * 		devID:设备ID
	 * 		type{热水:hot,冷水:cold}
	 * 		beginTime:实际出水时间
	 */
	public function begin() {
		$devID = ( int ) $this->input->post_get ( 'devID' );
		$type = ( string ) $this->input->post_get ( 'type' );
		$beginTime = ( float ) $this->input->post_get ( 'beginTime' );
		$mode = $this->getMode();
		// 检查输入
		if (empty ( $devID ) || empty ( $beginTime ) || ! in_array ( $type, array ( 'hot', 'cold' ) ) ) {
			$this->apiOutput->errorInput ();
		}
		// 检查余额是否足够
		$price = $this->price->getPrice ( $mode, $type );
		$balance = ( int ) $this->user->balance;
		if ($balance < $price) {
			$this->apiOutput->error ( '余额不足,请充值后再取水', - 99 );
		}
		// 检查该用户是否正在取水
		$unfinishOrders = $this->order->getUserUnfinishOrders ( $this->user->id );
		if (! empty ( $unfinishOrders )) {
			$this->apiOutput->error ( '您的账号有未完成的订单,请稍后再试!', - 3 );
		}
		// 检查设备并纪录用户使用过该设备
		$dev  = $this->userDev->addedDev($this->user->id, $devID);
		if ( ! $dev ) {
			$this->apiOutput->error ( '无该设备!', - 2 );
		} 

		// 创建订单
		$now = time ();
		$order = array ();
		$order ['price'] = $price;
		$order ['createTime'] = $now;
		$order ['beginTime'] = $beginTime;
		$order ['devID'] = $devID;
		$order ['userID'] = $this->user->id;
		$order ['type'] = $type == 'hot' ? 1 : 2;
		$order ['phoneID'] = $this->user->currentPhoneID;
		$order ['alias'] = $dev ['alias'];
		
		switch ($mode) {
			case BUY_MODE_ONCE : // 按次消费模式
				$order ['isFinish'] = 1;
				$order ['takeSec'] = self::ONCE_TAKE_SECS;
				$order ['endTime'] = $beginTime + 5;
				$order ['finishTime'] = $now;
				$order ['amount'] = $price;
				// 向用户扣钱成功后再插入到订单表
				$this->user->balance -= $price;
				if ($this->user->update ()) {
					$orderID = $this->order->insert ( $order );
				}
				break;
			case BUY_MODE_NORMAL : // 普通模式
				$order ['isFinish'] = 0;
				$orderID = $this->order->insert ( $order );
				if ($orderID) {
					// 存进订单队列
					$data = array(
							'_id' => $orderID, // 订单ID
							'state' => BUY_ORDER_STATE_BEGIN, // 订单状态
							'maxTakeSecs' => floor ( $balance / $price ), // 最大取水秒数
							'beginTime' => $beginTime, // 订单开始时的APP端时间戳
							'appTime' => $beginTime, // 每次通知的APP端时间戳
							'serverTime' => time (),//每次通知的服务器端时间戳
											
					);
					$res = $this->orderQueue->add($data);
					if ( ! $res ) {
						$this->apiOutput->errorSystem();
					}
				}
				break;
		}
		if ( empty($orderID) ) {
			$this->apiOutput->errorSystem ();
		}
		$msg = '开始取' . ($type == 'hot' ? '热水' : '冷水');
		$this->apiOutput->put ( 'status', 1 )
						->put ( 'orderID', $orderID )
						->put ( 'msg', $msg )
						->put ( 'balance', $this->user->balance )
						->out ();
	}
	/**
	 * 出水中:
	 * 	传入参数:
	 * 		orderID
	 * 		time
	 */
	public function flowing(){
// 		$this->checkInputAndOrder('flowing');
		$orderID = (int)$this->input->post_get('orderID');
		$appTime = (float)$this->input->post_get('time');
		$now     = time();
		if ( $orderID < 0 && $appTime<0 ) {
			$this->apiOutput->errorInput();
		}
		// 从订单队列中获取该订单
		$order = $this->orderQueue->findOneByID($orderID);
		if ( empty($order) ) {
			// 如果队列中没有,到订单表获取
			$order = $this->order->getOneById($orderID);
			if ( empty($order) ) {
				$this->apiOutput->error('无该订单',-21);
			}
			// 订单已结束
			if ( $order['isFinish']==1 ) {
				$this->apiOutput->put('status', 2)
								->put('takeSec',(int) $order['takeSec'])
								->put('amount', (int)$order['amount'])
								->msg('订单已因超时被处理');
				
			}else{// 如果之前订单未结束,补充进队列
				$data = array(
						'_id' => $orderID, // 订单ID
						'state' => BUY_ORDER_STATE_FLOWING, // 订单状态
						'maxTakeSecs' => floor ( $this->user->balance / $order['price'] ), // 最大取水秒数
						'beginTime' => $order['beginTime'], // 订单开始时的APP端时间戳
						'appTime' => $appTime, // 每次通知的APP端时间戳
						'serverTime' => $now,//每次通知的服务器端时间戳
				);
				$res = $this->orderQueue->add($data);
				// 返回成功信息
				$this->apiOutput->put('status',1)->out();
			}
		}
		// 本次通知时间小于上一次通知时间:结算
		if ( $appTime < $order['appTime'] ) {
			$endTime = $order['beginTime']+( $now-$order['serverTime'] )+3;
			$result  = $this->order->end($orderID, $endTime);
			$this->apiOutput->put('status', 2)
							->put('takeSec', $result['takeSec'])
							->put('amount', $result['amount'])
							->msg('订单异常被结算');
		}
		
		// 检查余额是否足够
		if ( $appTime+1 >= $order['beginTime']+$order['maxTakeSecs'] ) {
			$result = $this->order->end($orderID,$appTime);
			$this->apiOutput->put('status', 3)
							->put('takeSec', $result['takeSec'])
							->put('amount', $result['amount'])
							->msg('订单因余额不足被结算');
		}
		// 更新队列
		$res = $this->orderQueue->flowing($orderID,$appTime);
		
		if( $res ){
			$this->apiOutput->put('status',1)->out();
		}else{
			$this->apiOutput->errorSystem();
		}
	}
	/**
	 * 买水结束:
	 * 输入参数:
	 * 		orderID
	 * 		endTime
	 */
	public function end(){
		$orderID = (int) $this->input->post_get('orderID');
		$appTime = (float) $this->input->post_get('endTime');
		$now     = time();
		if ( $orderID<=0 || $appTime<=0 ) {
			$this->apiOutput->errorInput();
		}
		
		$order = $this->orderQueue->findOneByID($orderID);
		if ( empty($order) ) {
			// 如果队列中无此订单,从订单表查询
			$order = $this->order->getOneById($orderID);
			if ( empty($order) ) {
				$this->apiOutput->error('无该订单',-21);
			}
			$endTime = $order['beginTime'] + ( $now - $order['createTime'] );
		} else {
			$endTime = $appTime;
			if ( $appTime < $order['appTime'] ) {
				$endTime = $order['appTime'] + ( $now - $order['serverTime'] );
			}
		}
		$result = $this->order->end($orderID,$endTime);
		if( !empty($result) ){
			$this->apiOutput->put('status',1)
							->put('takeSec',$result['takeSec'])
							->put('amount',$result['amount'])
							->out();
		}else{
			$this->apiOutput->errorSystem();
		}
	}
	/**
	 * 获取当前消费模式
	 * @return int
	 */
	private function getMode(){
		$mode = (int)$this->input->post_get('mode');
		return $mode===1 ? BUY_MODE_ONCE : BUY_MODE_NORMAL;
	}
	
}
